<?php

namespace App\Service\Cruise\Mission;

use App\Enums\BaseErrorCode;
use App\Exceptions\Custom\ResponseHttpException;
use App\Library\FeiShu\SendFs;
use App\Library\Rms\RmsCurl;
use App\Library\Rms\RmsUserApi;
use App\Models\Cruise\CruiseOrderInputModel;
use App\Models\Cruise\CruiseOrderModel;
use App\Models\Cruise\CruiseTaskProjectModel;
use App\Models\Cruise\CruiseTemplateModel;
use App\Models\Shop\ShopModel;
use App\Models\Workflow\WorkflowV2OrderLogModel;
use App\Models\Workflow\WorkflowV2OrderNodeModel;
use App\Service\BaseService;
use App\Service\Renew\RenewService;
use App\Service\Workflow\WorkflowV2OrderService;
use App\Support\CustomForm\AttributeCruiseSupport;
use Illuminate\Support\Facades\DB;
use Kuafu\GeneralFs\BuildFs;

class WorkflowV2InputService extends CruiseOrderInputBaseService
{
    private ?CruiseOrderModel $cruiseOrderModel;
    private int               $userId;
    private int               $shopId;
    private int               $workflowOrderId;

    public function __construct(int $cruiseOrderId, int $userId, int $shopId = 0)
    {
        $this->userId  = $userId;
        $this->orderId = $cruiseOrderId;
        $this->shopId  = $shopId;

        if ($cruiseOrderId) {
            $this->cruiseOrderModel = CruiseOrderModel::query()->where('id', $cruiseOrderId)->first();
            if (!$this->cruiseOrderModel) {
                throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null,
                    "不存在的任务ID:{$cruiseOrderId}");
            }
        }

        parent::__construct($cruiseOrderId, CruiseTemplateModel::TYPE_7,
            CruiseTemplateModel::SYS_TEMPLATE_WORKFLOW_WORK_ORDER);
    }

    public function setWorkflowOrderId(int $workflowOrderId): self
    {
        $this->workflowOrderId = $workflowOrderId;
        return $this;
    }

    public function getCruiseOrderModel(): CruiseOrderModel
    {
        return $this->cruiseOrderModel;
    }

    /**
     * 初始化表单信息
     * @return void
     */
    public function initOrderInput(int $templateId = 0): void
    {
        if (!$templateId) {
            $templateId = CruiseTemplateModel::query()
                                             ->where('type', $this->templateType)
                                             ->where('sysTemplate', $this->sysTemplate)
                                             ->where('status', CruiseTemplateModel::STATUS_ON)
                                             ->value('id') ?? 0;
            if (!$templateId) {
                throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null,
                    "获取模板类型对应模板失败:{$this->templateType}");
            }
        }

        $this->cruiseOrderModel = CruiseOrderModel::query()->create([
            'shopId'       => $this->shopId,
            'createdByUid' => $this->userId,
            'templateId'   => $templateId,
            'orderNo'   => '',
            'type'      => $this->templateType,
            'status'    => CruiseOrderModel::STATUS_NOT_SUBMIT,
            'handlerId' => $this->userId,
        ]);
        $this->orderId          = $this->cruiseOrderModel->id;

//        // 幂等-不再创建
//        if (!$forceUpdate) {
//            return;
//        }

        $cruiseOrderInputModel = parent::baseInitOrderInput($templateId);

        // 初始化表单数据
        $this->initUserContentJson($this->shopId, $this->userId, $cruiseOrderInputModel);
    }

    public function getInputObjectFill(): array
    {
        $submit = $this->checkSubmit();

        if ($submit && in_array($this->cruiseOrderModel->status,
                [CruiseOrderModel::STATUS_NOT_SUBMIT, CruiseOrderModel::STATUS_NOT_MODIFY])) {
            $disable = false;
        } else {
            $disable = true;
        }

        $data              = parent::baseGetInputObjectFill($disable);
        $data['submit']    = $submit; // 提交权限

        return $data;
    }

    /**
     * 是否有提交权限
     * @return bool
     */
    private function checkSubmit(): bool
    {
        return $this->userId == $this->cruiseOrderModel->createdByUid;
    }

    public function saveUserContentJson(string $field, $value, array $auditValue = []): void
    {
        // 状态校验
        if (!in_array($this->cruiseOrderModel->status,
            [CruiseOrderModel::STATUS_NOT_SUBMIT, CruiseOrderModel::STATUS_NOT_MODIFY])) {
            $statusText = CruiseOrderModel::CRUISE_STATUS_MAPPING[$this->cruiseOrderModel->status] ?? '';
            BaseService::throwErr("当前状态: {$statusText}，不允许修改");
        }

        if (!$this->checkSubmit()) {
            BaseService::throwErr('没有提交权限');
        }


        parent::baseSaveUserContentJson($field, $value, $auditValue);
    }

    public function submitOrder(): void
    {
        // 状态校验
        if (!in_array($this->cruiseOrderModel->status,
            [
                CruiseOrderModel::STATUS_NOT_SUBMIT,
                CruiseOrderModel::STATUS_NOT_MODIFY,
                CruiseOrderModel::STATUS_NOT_REVIEW
            ])) {
            $statusText = CruiseOrderModel::CRUISE_STATUS_MAPPING[$this->cruiseOrderModel->status] ?? '';
            BaseService::throwErr("当前状态: {$statusText}，不允许提交");
        }

        // 角色校验
        if (!$this->checkSubmit()) {
            BaseService::throwErr('没有提交权限');
        }

        parent::baseSubmitOrder(true);

        $workflow = (new WorkflowV2OrderService($this->workflowOrderId, $this->userId));

        $nodeId = (int)WorkflowV2OrderNodeModel::query()->where('cruiseOrderId', $this->cruiseOrderModel->id)->where('status', WorkflowV2OrderNodeModel::STATUS_ING)->value('id');
        if (!$nodeId) {
            BaseService::throwErr("未找到进行中的节点");
        }

        $content = '';
        $imgFiles = [];

        // 查询有没有审批组件
        $inputs               = $this->inputArray('inputType');
        $approvalRejectModule = $inputs[AttributeCruiseSupport::INPUT_TYPE_APPROVAL_REJECT] ?? [];

        if ($approvalRejectModule) {

            $audit = $approvalRejectModule['value'] ?? AttributeCruiseSupport::CRUISE_CHECK_OK;

            // 审批内容
            $content = $inputs[AttributeCruiseSupport::INPUT_TYPE_TEXT]['value'] ?? '';

            // 审批附件
            $imgFiles = $inputs[AttributeCruiseSupport::INPUT_TYPE_IMG_FILE]['value'] ?? [];

            // 文件处理
            foreach ($imgFiles as &$imgFile) {
                if (isset($imgFile['path'])) {
                    $imgFile['path'] = ltrim(parse_url($imgFile['path'], PHP_URL_PATH), '/');
                }
                if (isset($imgFile['url'])) {
                    $imgFile['url'] = ltrim(parse_url($imgFile['url'], PHP_URL_PATH), '/');
                }
            }

            // 审核驳回
            if ($audit == AttributeCruiseSupport::CRUISE_CHECK_FAIL) {

                // TODO 考虑节点重置的操作!!!

            }

        } else {

            // 没有审批组件，默认就是提交
            $audit = WorkflowV2OrderLogModel::AUDIT_YES;
        }

        DB::beginTransaction();

        $nextNode = $workflow->finishNodeEnterNext(
            $nodeId,
            $audit,
            $content,
            $rejectNodeId = 0
        );

        // 提交后干的事
        $this->cruiseOrderModel->status    = CruiseOrderModel::STATUS_COMPLETE;
        $this->cruiseOrderModel->handlerId = 0;
        $this->cruiseOrderModel->save();

        // 当前节点完成
        if (!$nextNode || $nextNode->id != $nodeId) {

            // 日志完成
            (new WorkflowV2OrderLogModel())->finish($this->workflowOrderId, $nodeId, $this->userId, $audit, $content, $imgFiles);
        }

        // 下一个节点日志
        if ($nextNode && $nextNode->id != $nodeId) {
            (new WorkflowV2OrderLogModel())->add($this->workflowOrderId, $nextNode->id, 0);
        }

        DB::commit();
    }

    public function audit(array $data): void
    {
        // TODO: Implement audit() method.
    }

    private function initUserContentJson(int $shopId, int $userId, CruiseOrderInputModel $cruiseOrderInputModel)
    {
        $userContentJson    = json_decode($cruiseOrderInputModel->userContentJson, true);
        $inputObjectJsonArr = $cruiseOrderInputModel->inputObjectJsonArr;

        $shopModel = ShopModel::query()->where('id', $shopId)->first();

        foreach ($cruiseOrderInputModel->inputObjectJsonArr as $k1 => $positions) {
            foreach ($positions['projects'] as $k2 => $project) {
                $projectObj = unserialize($project);

                $meanType = $projectObj->meanType;
                $field    = $projectObj->inputName;

                switch ($meanType) {

                    // 门店信息
                    case CruiseTaskProjectModel::MEAN_TYPE_SHOP_CODE_NAME:

                        $shopCode = $shopModel->shopCode;
                        $shopName = $shopModel->name;

                        $userContentJson[$field] = $shopCode . $shopName;
                        $projectObj->setCustomAttribute(['disabled', true]);
                        break;

                    // 门店分公司
                    case CruiseTaskProjectModel::MEAN_TYPE_SHOP_BRANCH:
                        $userContentJson[$field] = $shopModel->branch;

                        break;

                    // 需求提交人隐私信息
                    case CruiseTaskProjectModel::MEAN_TYPE_SUBMIT_USER_PRIVACY:

                        $user = (new RmsUserApi())->getUserInfoByIds([$userId])['data'][0] ?? [];
                        $username = $user['username'] ?? '';
                        $mobile = $user['mobile'] ?? '';

                        $userContentJson[$field] = preg_replace_callback('/([\x{4e00}-\x{9fa5}]*)(\d{11})/u', function ($matches) {
                            {
                                // 姓名只显示第一个字符，其余用*代替
                                if (mb_strlen($matches[1]) > 1) {
                                    $matches[1] = mb_substr($matches[1], 0, 1) . str_repeat('*', mb_strlen($matches[1]) - 1);
                                }

                                // 手机号中间四位用*代替
                                $matches[2] = substr_replace($matches[2], '****', 3, 4);

                                return $matches[1] . $matches[2];
                            }
                        }, $username . $mobile);

                        break;
                }

                $inputObjectJsonArr[$k1]['projects'][$k2] = serialize($projectObj);
            }

            $cruiseOrderInputModel->userContentJson = json_encode($userContentJson);
            $cruiseOrderInputModel->inputObjectJson = json_encode($inputObjectJsonArr);
            $cruiseOrderInputModel->save();
        }
    }
}
